//
//  ChatViewModel.swift
//  WebSocketDemo
//
//  Created by 姬向阳 on 2020/5/8.
//  Copyright © 2020 SUNNYJ. All rights reserved.
//

import SwiftUI
import SwiftyJSON

/// 聊天管理者
class ChatManager: ObservableObject {
    /// socketManager单例
    var socketManager = WebSocketManager.shared
    /// 是否连接上服务器
    @Published var isConnected: Bool = false
    @Published var avatar: String = ""
    
    /// 将显示到ListView中的消息数组
    @Published var messages: [Message] = [
    ]
    
    init() {
        socketManager.socket.onEvent = { event in
            switch event {
                case .connected(let headers):
                    self.isConnected = true
                    print("websocket is connected: \(headers)")
                    guard let origin = headers["Origin"] else { break }
                    let now = Date()
                    self.messages.append(Message(time: now.description(with: .autoupdatingCurrent), author: "System", text: "成功连接Websocket服务器:\n\(origin)", color: "gray"))
                    self.register()
                case .disconnected(let reason, let code):
                    self.isConnected = false
                    print("websocket is disconnected: \(reason) with code: \(code)")
                case .text(let string):
                    self.recieveMessage(string)
                case .binary(let data):
                    print("Received data: \(data.count)")
                case .ping(_):
                    break
                case .pong(_):
                    break
                case .viabilityChanged(_):
                    break
                case .reconnectSuggested(_):
                    break
                case .cancelled:
                    self.isConnected = false
                case .error(let error):
                    self.isConnected = false
                    //handleError(error)
                    print(error?.localizedDescription ?? "Unknown Error.")
            }
        }
    }

    /// 连接服务器
    func connectServer() {
        socketManager.connect()
    }
    
    /// 断开连接
    func disConnect() {
        socketManager.disConnect()
    }
    
    /// 连接服务器后,发送avatar注册身份
    func register() {
        socketManager.sendString(string: avatar)
    }
    
    /// 发送消息
    /// - Parameter string: 消息字符串
    func sendMessage(_ string: String) {
        socketManager.sendString(string: string)
    }
    
    // 将收到的String转化为Message,写得很烂,因为Codable协议用不了,JSON同参不同型,暂未找到解决方案,用了最蠢的SwiftyJSON
    func recieveMessage(_ string: String) {
        guard let dataFromString = string.data(using: .utf8, allowLossyConversion: false) else {
            fatalError("Can not load data from string.")
        }
        let json = try! JSON(data: dataFromString)
        if json["type"].string == "color" {
            let now = Date()
            let msg = Message(time: now.description(with: .autoupdatingCurrent), author: "System", text: "Login with \(json["data"].string ?? "error") color.", color: json["data"].string ?? "error")
            messages.append(msg)
        } else if json["type"].string == "history" {
            for (_,dict):(String, JSON) in json["data"] {
                self.dealWithMessage(dict)
            }
        } else if json["type"].string == "message" {
            self.dealWithMessage(json["data"])
        }
    }
    
    // 手动将JSON格式的Message转为Message Model
    func dealWithMessage(_ dict: JSON) {
        let millTime = dict["time"].int ?? 0
        let time = Int(millTime/1000)
        let author = dict["author"].string ?? "Unknown author"
        let text = dict["text"].string ?? ""
        let color = dict["color"].string ?? ""
        var isMe: Bool { author == self.avatar }
        let msg = Message(time: Dater.messageTime(time), author: author, text: text, color: color, isMe: isMe)
        messages.append(msg)
    }

}
